package com.guide.framework.datasource;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.StringUtils;

public class DataSourceBeforeAdvice implements MethodBeforeAdvice , ApplicationContextAware{

	protected static final Logger logger = LoggerFactory.getLogger(DataSourceBeforeAdvice.class);
	
	private ApplicationContext applicationContext;
	
	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {		
		this.applicationContext = applicationContext;		
	}
	
	@SuppressWarnings("unchecked")
	public void before(Method method, Object[] args, Object target) throws Throwable {
		
		ShardingKey shardingKey = null;
		Object shardValue = null;
		Annotation[][] annotations = method.getParameterAnnotations();
		
		for(int i =0;i<annotations.length;i++) {
			for(int j=0;j<annotations[i].length;j++) {
				if(annotations[i][j] instanceof ShardingKey) {
					shardingKey = (ShardingKey)annotations[i][j];
					shardValue = args[i];
					break;
				}
			}
		}
		
		if(shardingKey != null && !StringUtils.isEmpty(shardingKey.shardManager())) {
			logger.debug(shardingKey.shardManager());
			
			ShardingManager<Object> manager = this.applicationContext.getBean(shardingKey.shardManager(),ShardingManager.class);
			
			if(manager != null) {
				
				String dataSourceKey = manager.getDataSourceKey(shardValue);
				DynamicDataSourceHolder.setThreadDataSource(dataSourceKey);
			}
		}
	}

	
}
